`timescale 1ns/1ps

module  wptr_full(
                  //output
                  ff,
                  wp_bin,
                  wp_gray,

                 //input
                  wr_clk,
                  wr_rst,
                  wr_clr,
                  wen,
                  rp_s         
                 );
                 
  parameter aw=10;
  
  
output         ff;                   //low active
output [aw:0]  wp_bin;
output [aw:0]  wp_gray;

input          wr_clk;
input          wr_rst;
input          wr_clr;
input          wen;
input  [aw:0]  rp_s;


///////////////////////////////////////////////////////////////////////
//local wires
//
reg            ff;
reg    [aw:0]  wp_bin;
reg    [aw:0]  wp_gray;

wire	[aw:0]		wp_bin_next;
wire	[aw:0]		wp_gray_next;
wire	[aw:0]		rp_bin_x;
                 
///////////////////////////////////////////////////////////////////////
//  write pointers logic
//  
always @(posedge wr_clk or negedge wr_rst )
if(!wr_rst)
	wp_bin <= #1 {aw+1{1'b0}};
else if(wr_clr)
	wp_bin <= #1 {aw+1{1'b0}};
else if(!wen)	
	wp_bin <= #1 wp_bin_next;

always @(posedge wr_clk or negedge wr_rst)
if(!wr_rst)
	wp_gray <= #1 {aw+1{1'b0}};
else if(wr_clr)
	wp_gray <= #1 {aw+1{1'b0}};
else if(!wen)
	wp_gray <= #1 wp_gray_next;

assign wp_bin_next  = wp_bin + {{aw{1'b0}},1'b1};
assign wp_gray_next = wp_bin_next ^ {1'b0, wp_bin_next[aw:1]};

//synopsys translate_off
//--------------Only for Debug/Statistics-------------------
reg [aw:0] wr_status;
always @(posedge wr_clk or negedge wr_rst)
if(!wr_rst)	
	wr_status <= #1 {aw+1{1'b0}};
else if(wr_clr)	
	wr_status <= #1 {aw+1{1'b0}};
else
	wr_status <= #1 wp_bin - rp_bin_x;
//synopsys translate_on

///////////////////////////////////////////////////////////////////////
//  full flag logic
//  

assign rp_bin_x = rp_s ^ {1'b0, rp_bin_x[aw:1]};	// convert gray to binary

always @(posedge wr_clk or negedge wr_rst)	
if(!wr_rst)	
	ff <= #1 1;
else if(wr_clr)	
	ff <= #1 1;
else
	ff <= #1 ~(((wp_bin[aw-1:0] == rp_bin_x[aw-1:0]) & (wp_bin[aw] != rp_bin_x[aw])) |
    (!wen & (wp_bin_next[aw-1:0] == rp_bin_x[aw-1:0]) & (wp_bin_next[aw] != rp_bin_x[aw])));
  

endmodule    